#ifndef ELEMENT_H_
#define ELEMENT_H_

#include "Node.h"
#include "Matrix.h"
#include "Vector.h"

#define TRIANGULAR 3

class Element{
protected:
	Node *nodes;
	int label;
	bool exposed;
	double dt;
public:
	Element(){
		nodes=new Node[TRIANGULAR+1];
		exposed=false;
		dt=0.0;
	}
	virtual ~Element(){}
	virtual int & Label(){return label;}
   	virtual void setLabel(const int &label){this->label=label;}
   	
   	virtual Node & operator[](int i){return nodes[i];}

	virtual double length(int i,int j){
		double dx=Dx(i,j);
		double dy=Dy(i,j);
		return sqrt(dx*dx+dy*dy);
	}

	virtual double area(){
		 double a = (nodes[1].X() * nodes[2].Y()) - (nodes[2].X()
				* nodes[1].Y()) + (nodes[3].X() * nodes[1].Y())
				- (nodes[1].X() * nodes[3].Y()) + (nodes[2].X()
				* nodes[3].Y()) - (nodes[3].X() * nodes[2].Y());
		  return fabs(a / 2);
	}

	virtual double normal1(int i,int j){
	    double l=length(i,j);
	    double dx=Dx(i,j);
	    return -dx/l;
	}

	virtual double normal2(int i,int j){
	    double l=length(i,j);
	    double dy=Dy(i,j);
	    return dy/l;
	}

	virtual Matrix isoB(){
	    Vector b=B();
	    Matrix bm=Matrix::isoColumn(b(1),b(2),b(3));
	    return bm;
	}

	virtual Matrix isoC(){
	   Vector c=C();
	   Matrix cm=Matrix::isoColumn(c(1),c(2),c(3));
	   return cm;
	}

	virtual Vector A(){
	    Vector A = Vector(TRIANGULAR);
	    double a1 = nodes[2].X() * nodes[3].Y() - nodes[3].X()
			* nodes[2].Y();
	    A.set(1, a1);
	    double a2 = nodes[3].X() * nodes[1].Y() - nodes[1].X()
			* nodes[3].Y();
	    A.set(2, a2);
	    double a3 = nodes[1].X() * nodes[2].Y() - nodes[2].X()
			* nodes[1].Y();
		A.set(3, a3);
		return A;
	}

	virtual Vector B(){
	    Vector B = Vector(TRIANGULAR);
	    double b1 = nodes[2].Y() - nodes[3].Y();
	    B.set(1, b1);
	    double b2 = nodes[3].Y() - nodes[1].Y();
	    B.set(2, b2);
	    double b3 = nodes[1].Y() - nodes[2].Y();
	    B.set(3, b3);
	    return B;
	}

	virtual Vector C() {
		Vector C = Vector(TRIANGULAR);
		double c1 = nodes[3].X() - nodes[2].X();
		C.set(1, c1);
		double c2 = nodes[1].X() - nodes[3].X();
		C.set(2, c2);
		double c3 = nodes[2].X() - nodes[1].X();
		C.set(3, c3);
		return C;
	}

	virtual int indexOf(Node &node){
		int index = 0;
		for (int i = 1; i <= TRIANGULAR; i++) {
			if (node == nodes[i]) {
				index = i;
				break;
			}
		}
		return index;
	}
	virtual void addNode(int i,const Node &n){
	     nodes[i]=n;	
	}
	virtual double & Dt(){return dt;}
	virtual void setDt(const double &dt){this->dt=dt;}
	virtual bool & isExposed(){return exposed;}
	virtual double Dx(int i,int j){
	   return (nodes[j].X()-nodes[i].X());	
	}
	virtual double Dy(int i,int j){
	   return (nodes[j].Y()-nodes[i].Y());	
	}
};
#endif /**/
